/*
    Project:        Home Power Control
    File:           HPCBarometer.h
    Author:         christian@karunamusic.at
                    Code based on this: http://cognitivedissonance.ca/cogware/BMP085/BMP085_C++.tar.bz2
    Date:           02.2015
    Description:    Sensor (BMP180) to read the barometric pressure.
 */

#ifndef HPCBAROMETER_H
#define HPCBAROMETER_H

#include <QString>
#include <HPCSensor.h>

class HPCBarometer : public HPCSensor
{
    Q_OBJECT
public:
    static const double SEA_LEVEL_PRESSURE;
    static const int    CONTROL_REG;
    static const int    DATA_REG;
    static const int    TEMP_COMMAND;
    static const double ALT_EXP;

    /**< Compound type for returning data, see getBoth(). */
    typedef struct
    {
        float celcius;
        float kPa;
    } TReading;
    /**< See sec. 3.3 of the datasheet for the significance of the oversampling setting. */
    enum OversamplingSetting
    {
        OSS_LOW = 0,
        OSS_STANDARD = 1,
        OSS_HIGH = 2,
        OSS_ULTRAHIGH = 3
    };
    /**< If 'ok' is false, check 'err'.  This should be done after the object is constructed. */
    bool ok;
    QString err;
    /** You can change 'oss' and 'hiRes' any time; the latter is on by default
     *  and means we use 19 bits of resolution for the pressure reading instead
     *  of 16 (see, eg. datasheet sec. 4.5).
     */
    OversamplingSetting oss;
    bool hiRes;

    /** \brief Constructor
     *
     * \param name name of the sensor.
     * \param id database id of the sensor.
     * \param i2caddr the address on the i2c-bus.
     */
    explicit HPCBarometer( const QString& name, quint32 id, quint8 i2caddr );
    /** \brief Destructor.
     */
    virtual ~HPCBarometer();

    /** \brief Get class with content as printable string.
     *
     * \return string
     */
    QString asString() const;

protected:
    /** \brief Get a value from the sensor.
     */
    virtual void Measure();

    /** \brief returns the temperature in °C.
     * The sensor has a resolution of 1/10th a degree.
     */
    float getCelcius();
    /** \brief Read temperature and pressure.
     * Since it is necessary to read the temperatature in order to
     * calculate the pressure, getBoth() does both.
     */
    TReading getBoth();
    /** \brief Given a reading, returns the pressure adjusted for temperature.
     */
    static float adjustedPressure(TReading raw );
    /**< Simple conversions. */
    static float celcius2Fahrenheit (float t);
    static float kPa2inHg (float t);

    qint16 ac1;
    qint16 ac2;
    qint16 ac3;
    quint16 ac4;
    quint16 ac5;
    quint16 ac6;
    qint16 b1;
    qint16 b2;
    qint16 mb;
    qint16 mc;
    qint16 md;

    float  getCelcius( long b5 );
    long   getB5Value();
    qint16 readWord( int addr );

private:
    int m_I2C; /**< filehandle for i2c-device */

    /** This could be a sort of singleton, or static factory based
     *  on dev node + I2C address.  Instead, just forbid copies, etc.
     *  by leaving these private and undefined
     */
    HPCBarometer (const HPCBarometer&);
    HPCBarometer& operator= (const HPCBarometer&);
};

#endif // HPCBAROMETER_H
